package paypal

import (
	"context"
	"errors"
	"fmt"
	"gitee.com/bobo-rs/innovideo-services/library/models"
	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/util/gconv"
	"github.com/plutov/paypal/v4"
	"strconv"
)

// Payment 使用PayPal支付创建订单
func (p *SPayPal) Payment(ctx context.Context, tradeNo string, amount float64, other interface{}) (res interface{}, err error) {
	// 捕捉错误日志
	defer func() {
		if err != nil {
			g.Log().Debug(ctx, `PayPal支付创建支付订单失败`, tradeNo, amount, other, err)
		}
	}()
	// 验证其他参数
	param, err := p.processOtherParam(other)
	if err != nil {
		return nil, err
	}

	fmt.Println(tradeNo, amount, param)
	// 实例PayPal客户端
	client, err := p.Client(ctx)
	if err != nil {
		return nil, err
	}

	// 支付信息
	req := paypal.PurchaseUnitRequest{
		Amount: &paypal.PurchaseUnitAmount{
			Currency: param.Currency,
			Value:    strconv.FormatFloat(amount, 'f', 2, 64),
		},
		Description: param.Content,
		CustomID:    tradeNo, // 商户交易号
	}

	// 设置页面跳转路由
	appContext := &paypal.ApplicationContext{
		ReturnURL: param.ReturnUrl,
		CancelURL: param.CancelUrl,
	}
	var reqs []paypal.PurchaseUnitRequest
	reqs = append(reqs, req)

	// 创建订单
	r, err := client.CreateOrder(ctx, p.intent, reqs, nil, appContext)
	if err != nil {
		return nil, err
	}

	// 记录日志
	g.Log().Info(ctx, `PayPal支付-创建订单成功`, r)
	return map[string]interface{}{
		`pay_no`:   r.ID,
		`trade_no`: tradeNo,
		`pay_url`:  p.processPayLink(r.Links, param.LinkRel),
	}, nil
}

// ConfirmPayment 回调PayPal创建订单确认订单是否支付成功（很重要，不回调此方法，用户无法完成支付）
func (p *SPayPal) ConfirmPayment(ctx context.Context, payNo string) (res *models.ConfirmPayResponse, err error) {
	// 打印错误消息
	defer func() {
		if err != nil {
			g.Log().Debug(ctx, `PayPal回调支付确认失败`, err)
		}
	}()

	// 客户端初始化
	client, err := p.Client(ctx)
	if err != nil {
		return nil, fmt.Errorf(`实例客户端失败%w`, err)
	}

	// 实例订单是否确认支付
	req := paypal.CaptureOrderRequest{}
	resp, err := client.CaptureOrder(ctx, payNo, req)
	if err != nil {
		return nil, fmt.Errorf(`确认授权支付失败%w`, err)
	}

	// 打印订单信息
	g.Log().Debug(ctx, `PayPal支付-回调确认订单信息`, resp)
	if resp.Status != `COMPLETED` {
		return nil, fmt.Errorf(`支付失败%s`, resp.Status)
	}

	// 支付成功
	return &models.ConfirmPayResponse{
		PayNo:   resp.ID,
		TradeNo: resp.PurchaseUnits[0].Payments.Captures[0].CustomID,
	}, nil
}

// processOtherParam 处理其他参数
func (p *SPayPal) processOtherParam(other interface{}) (*OtherParam, error) {
	if other == nil {
		return nil, errors.New(`missing other parameters`)
	}
	item := &OtherParam{
		Currency: `USD`,
	}
	if err := gconv.Scan(other, &item); err != nil {
		return nil, fmt.Errorf(`format other parameters failed %w`, err)
	}
	// 货币，默认美元
	if item.Currency == `` || item.CancelUrl == `` || item.ReturnUrl == `` {
		return nil, errors.New(`currency or cancelUrl or returnUrl required not in empty`)
	}
	// 支付链接类型
	if item.LinkRel == `` {
		item.LinkRel = defaultLinkRel
	}
	return item, nil
}

// processPayLink 获取指定支付PayPal地址
func (p *SPayPal) processPayLink(links []paypal.Link, rel string) string {
	var payLink string // self,approve,update,capture
	for _, link := range links {
		if link.Rel == rel {
			payLink = link.Href
			break
		}
	}
	return payLink
}
